﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QMessageBox>
#include <QFileDialog>
#include <QDir>
#include <QFileInfo>
#include <windows.h>
#include <QSettings>
#include <QTimer>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
    , m_scmHandle(nullptr)
    , m_serviceHandle(nullptr)
    , m_nginxPath("")
    , m_serviceName("nginx")
    , m_serviceDescription("")
    , m_isServiceInstalled(false)
    , m_statusCheckTimer(new QTimer(this))
{
    ui->setupUi(this);

    // 加载配置
    loadConfig();

    // 连接到服务控制管理器
    m_scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
    if (!m_scmHandle) {
        QMessageBox::critical(this, "Error", "Failed to connect to service control manager.");
        return;
    }

    // 打开 Nginx 服务
    m_serviceHandle = OpenService(m_scmHandle, m_serviceName.toStdWString().c_str(), SERVICE_ALL_ACCESS);
    if (m_serviceHandle) {
        // 服务已存在
        m_isServiceInstalled = true;
        DWORD startupType;
        if (QueryServiceConfig(m_serviceHandle, NULL, 0, &startupType)) {
            ui->autostartCheckBox->setChecked(startupType == SERVICE_AUTO_START);
        }
        ui->serviceNameLineEdit->setEnabled(false); // 服务安装后不可更改名称
        ui->serviceDescriptionLineEdit->setEnabled(false); // 服务安装后不可更改描述
    } else {
        // 服务不存在
        m_isServiceInstalled = false;
        ui->startButton->setEnabled(false);
        ui->stopButton->setEnabled(false);
        ui->restartButton->setEnabled(false);
        ui->autostartCheckBox->setEnabled(false);
    }

    // 设置初始值
    ui->serviceNameLineEdit->setText(m_serviceName);
    ui->nginxPathLineEdit->setText(m_nginxPath);
    ui->serviceDescriptionLineEdit->setText(m_serviceDescription);

    // 定时查询服务状态
    connect(m_statusCheckTimer, &QTimer::timeout, this, &MainWindow::checkServiceStatus);
    m_statusCheckTimer->start(5000); // 每5秒查询一次
}

MainWindow::~MainWindow()
{
    if (m_serviceHandle) {
        CloseServiceHandle(m_serviceHandle);
    }
    if (m_scmHandle) {
        CloseServiceHandle(m_scmHandle);
    }
    delete ui;
}

void MainWindow::on_startButton_clicked()
{
    if (StartService(m_serviceHandle, 0, NULL)) {
        qDebug() << "Nginx started successfully.";
    } else {
        qDebug() << "Failed to start Nginx: " << GetLastError();
    }
}

void MainWindow::on_stopButton_clicked()
{
    SERVICE_STATUS status;
    if (ControlService(m_serviceHandle, SERVICE_CONTROL_STOP, &status)) {
        qDebug() << "Nginx stopped successfully.";
    } else {
        qDebug() << "Failed to stop Nginx: " << GetLastError();
    }
}

void MainWindow::on_restartButton_clicked()
{
    SERVICE_STATUS status;
    if (ControlService(m_serviceHandle, SERVICE_CONTROL_STOP, &status)) {
        Sleep(2000); // 等待服务停止
        if (StartService(m_serviceHandle, 0, NULL)) {
            qDebug() << "Nginx restarted successfully.";
        } else {
            qDebug() << "Failed to restart Nginx: " << GetLastError();
        }
    } else {
        qDebug() << "Failed to stop Nginx: " << GetLastError();
    }
}

void MainWindow::on_autostartCheckBox_toggled(bool checked)
{
    DWORD startupType = checked ? SERVICE_AUTO_START : SERVICE_DEMAND_START;
    if (ChangeServiceConfig(m_serviceHandle, SERVICE_NO_CHANGE, startupType, SERVICE_NO_CHANGE, NULL, NULL, NULL, NULL, NULL, NULL, NULL)) {
        qDebug() << "Autostart setting changed successfully.";
    } else {
        qDebug() << "Failed to change autostart setting: " << GetLastError();
    }
}

void MainWindow::on_selectNginxPathButton_clicked()
{
    QString path = QFileDialog::getOpenFileName(this, "Select Nginx Executable", "", "Executable Files (*.exe)");
    if (!path.isEmpty()) {
        m_nginxPath = path;
        ui->nginxPathLineEdit->setText(path);
    }
}

void MainWindow::on_installServiceButton_clicked()
{
    if (m_nginxPath.isEmpty()) {
        QMessageBox::warning(this, "Warning", "Please select the Nginx executable first.");
        return;
    }

    if (installService(m_nginxPath, m_serviceName, m_serviceDescription)) {
        QMessageBox::information(this, "Success", "Nginx service installed successfully.");
        m_serviceHandle = OpenService(m_scmHandle, m_serviceName.toStdWString().c_str(), SERVICE_ALL_ACCESS);
        if (m_serviceHandle) {
            m_isServiceInstalled = true;
            updateServiceControls();
            saveConfig(); // 保存配置
        }
    } else {
        QMessageBox::critical(this, "Error", "Failed to install Nginx service.");
    }
}

void MainWindow::on_uninstallServiceButton_clicked()
{
    if (uninstallService()) {
        QMessageBox::information(this, "Success", "Nginx service uninstalled successfully.");
        m_serviceHandle = nullptr;
        m_isServiceInstalled = false;
        updateServiceControls();
        saveConfig(); // 保存配置
    } else {
        QMessageBox::critical(this, "Error", "Failed to uninstall Nginx service.");
    }
}

void MainWindow::on_serviceNameLineEdit_textChanged(const QString &text)
{
    if (!m_isServiceInstalled) {
        m_serviceName = text;
    }
}

void MainWindow::on_serviceDescriptionLineEdit_textChanged(const QString &text)
{
    if (!m_isServiceInstalled) {
        m_serviceDescription = text;
    }
}

void MainWindow::checkServiceStatus()
{
    if (m_isServiceInstalled) {
        queryServiceStatus();
    }
}

void MainWindow::loadConfig()
{
    QSettings settings("config.ini", QSettings::IniFormat);
    m_serviceName = settings.value("Service/Name", "nginx").toString();
    m_nginxPath = settings.value("Service/Path", "").toString();
    m_serviceDescription = settings.value("Service/Description", "").toString();
}

void MainWindow::saveConfig()
{
    QSettings settings("config.ini", QSettings::IniFormat);
    settings.setValue("Service/Name", m_serviceName);
    settings.setValue("Service/Path", m_nginxPath);
    settings.setValue("Service/Description", m_serviceDescription);
}

bool MainWindow::installService(const QString &servicePath, const QString &serviceName, const QString &description)
{
    // 构建完整的命令行参数，包括配置文件路径
    QString commandLine = QStringLiteral("\"%1\" -p \"%2\"").arg(servicePath).arg(QFileInfo(servicePath).absolutePath());

    SC_HANDLE hService = CreateService(
        m_scmHandle,
        serviceName.toStdWString().c_str(),
        description.toStdWString().c_str(),
        SERVICE_ALL_ACCESS,
        SERVICE_WIN32_OWN_PROCESS,
        SERVICE_AUTO_START,
        SERVICE_ERROR_NORMAL,
        servicePath.toStdWString().c_str(),
        NULL, NULL, NULL, NULL, commandLine.toStdWString().c_str()
    );

    if (hService) {
        CloseServiceHandle(hService);
        return true;
    }

    return false;
}

bool MainWindow::uninstallService()
{
    if (m_serviceHandle) {
        if (DeleteService(m_serviceHandle)) {
            CloseServiceHandle(m_serviceHandle);
            m_serviceHandle = nullptr;
            return true;
        }
    }

    return false;
}

void MainWindow::updateServiceControls()
{
    ui->startButton->setEnabled(m_isServiceInstalled);
    ui->stopButton->setEnabled(m_isServiceInstalled);
    ui->restartButton->setEnabled(m_isServiceInstalled);
    ui->autostartCheckBox->setEnabled(m_isServiceInstalled);
    ui->serviceNameLineEdit->setEnabled(!m_isServiceInstalled);
    ui->serviceDescriptionLineEdit->setEnabled(!m_isServiceInstalled);
}

void MainWindow::queryServiceStatus()
{
    if (m_serviceHandle) {
        ZeroMemory(&m_serviceStatus, sizeof(SERVICE_STATUS_PROCESS));
        DWORD bytesNeeded;
        if (QueryServiceStatusEx(m_serviceHandle, SC_STATUS_PROCESS_INFO, (LPBYTE)&m_serviceStatus, sizeof(SERVICE_STATUS_PROCESS), &bytesNeeded)) {
            switch (m_serviceStatus.dwCurrentState) {
                case SERVICE_RUNNING:
                    ui->statusLabel->setText("Running");
                    break;
                case SERVICE_STOPPED:
                    ui->statusLabel->setText("Stopped");
                    break;
                case SERVICE_START_PENDING:
                    ui->statusLabel->setText("Starting...");
                    break;
                case SERVICE_STOP_PENDING:
                    ui->statusLabel->setText("Stopping...");
                    break;
                default:
                    ui->statusLabel->setText("Unknown state");
            }
        } else {
            ui->statusLabel->setText("Failed to query status");
        }
    }
}
